<?php

namespace XWAM\Addon\PXCallSystem\Controller;

/**
 * 语音文件控制器
 *
 * @author Alen
 * @since 1.0 2014-6-19 by sutroon
 */
class MusicController extends AppbaseController {

    protected $moh_waiting_dir = '/var/lib/asterisk/moh';
    protected $sounds_other_dir = '/var/lib/asterisk/sounds';

    public function index() {
        $this->display();
    }

    public function get_music_search_data() {
        $search = I();
        $where['exTags'] = array('in', array('sounds', 'moh'));
        if (!$this->isSuperAdmin) {
            $where['siteID'] = $this->loginData['siteID'];
        }
        if ($search['siteID']) {
            $where['siteID'] = $search['siteID'];
        }
        return array('where' => $where);
    }

    public function get_music_list_json() {
        $search_data = $this->get_music_search_data();
        $list = AddonD('Music')->get_music_list($search_data['where']);
        $this->ajaxReturn($list);
    }

    /**
     * 获取子目录列表
     */
    public function get_subdir_json() {
        $field = I('field');
        $where['exTags'] = I('type');
        if ($this->isSuperAdmin) {
            $where['siteID'] = I('siteID');
        } else {
            $where['siteID'] = $this->loginData['siteID'];
        }
        switch ($field) {
            case 'iddir':
                $out = M('tgeneral_file')->where($where)->field('id, dirName as text')->select();
                break;
            case 'pathdir':
                //$out = M('tgeneral_file')->where($where)->field("replace(filePath,'//','/') as id, dirName as name")->select();
                $arr = M('tgeneral_file')->where($where)->field("filePath as id, dirName as text")->select();
                foreach ($arr as $row) {
                    $id = $row['id'];
                    $id = str_replace('//', '/', $id);
                    if (false !== ($pos = strrpos($id, '.'))) {
                        $id = substr($id, 0, $pos);
                    }
                    $out[] = array('id' => $id, 'text' => $row['text']);
                }
                break;
            case 'filenamedir':
                //$out = M('tgeneral_file')->where($where)->field("concat(dirName,'/',REVERSE(LEFT(REVERSE(filePath),INSTR(REVERSE(filePath),'/')-1))) as id, dirName as name")->select();                
                $arr = M('tgeneral_file')->where($where)->field("filePath as id, dirName as text")->select();
                foreach ($arr as $row) {
                    $id = $row['id'];
                    $id = substr($id, strrpos($id, '/') + 1);
                    if (false !== ($pos = strrpos($id, '.'))) {
                        $id = substr($id, 0, strlen($id) - $pos - 1);
                    }
                    $out[] = array('id' => $row['text'] . $id, 'name' => $row['text']);
                }
                break;
            default:
                $arr = M('tgeneral_file')->where($where)->distinct(true)->getField('dirName', true);
                foreach ($arr as $item) {
                    $out[] = array('id' => $item, 'text' => $item);
                }
                break;
        }
        $this->ajaxReturn($out);
        //$str = sofunc_get_distinct_fields_json('tgeneral_file', $where, 'dirName');
        //$this->ajaxReturn($str);
    }

    /**
     * 获取文件名
     */
    public function get_vocfile_json() {
        $type = I('type');
        $where['exTags'] = $type;
        if ($this->isSuperAdmin) {
            $where['siteID'] = I('siteID');
        } else {
            $where['siteID'] = $this->loginData['siteID'];
        }
        $data = M('tgeneral_file')->cache(true)->where($where)->field(array("concat(dirName,'/',left(fileName,length(fileName)-4)) as id", 'left(fileName,length(fileName)-4) as text'))->select();
        $this->ajaxReturn($data);
    }

    // 从文件夹同步到数据库
    public function update_db() {
        $arr1 = $this->get_insert_sqls($this->moh_waiting_dir, 'moh');
        $arr2 = $this->get_insert_sqls($this->sounds_other_dir, 'sounds');
        $arr = array_merge($arr1, $arr2);
        $M = new \Think\Model\AdvModel();
        $M->execute('delete from tgeneral_file where exTags in("sounds","moh");');
        $result = $M->patchQuery($arr);
        if ($result === false) {
            $this->ajaxMsg(false, '更新失败!');
        } else {
            $this->ajaxMsg(true, '数据库更新成功!', AddonU('VocFile/index'));
        }
    }

    public function item_save() {
        $siteID = I('siteID');
        $type = I('type');
        $dirname = I('dirName');
        $volume = I('volume');
        $err = '';
        if (!$type) {
            $err .= '请选择语音类型!<br />';
        }
        if (!$dirname) {
            $err .= '请填写子目录!<br />';
        }
        if ($err) {
            $this->ajaxMsg(false, $err);
        }
        if ($type == 'moh') {
            $dir = $this->moh_waiting_dir;
            $allowExts = array('mp3', 'wav');
            // $allowExts = array('mp3');
        } else {
            $dir = $this->sounds_other_dir;
            $allowExts = array('g729', 'mp3', 'wav');
            // $allowExts = array('g729', 'mp3');
        }
        if (!sofn_start_with($dirname, 'xcall_')) {
            $dirname = 'xcall_' . $siteID . '_' . $dirname;
        }
        $dir .= '/' . $dirname . '/';
        if ($type == 'moh' && is_dir($dir)) {
            $this->ajaxMsg(false, '子目录已存在!');
        }

        if (isset($_FILES['fileUrl']['name'])) {
            $filename = $_FILES['fileUrl']['name'];
            if (strpos($filename, ' ') !== false) {
                $this->ajaxMsg(false, '文件名不能包含空格!');
            }
            $ext = substr($filename, strrpos($filename, '.') + 1);
            $fnotext = substr($filename, 0, strrpos($filename, '.'));
            if (!in_array($ext, $allowExts)) {
                $this->ajaxMsg(false, '文件格式有误!');
            }
        } else {
            $this->ajaxMsg(false, '未选择文件!');
        }
        $dir = str_replace('//', '/', $dir);
        $data['createdTime'] = date('Y-m-d H:i:s');
        $data['dirName'] = $dirname; // xcall_13_002
        $data['exTags'] = $type; // moh
        $data['siteID'] = $siteID;
        $data['fileName'] = 'wav_' . $fnotext . '.wav';
        //$data['filePath'] = str_replace('//', '/', $dir . '/wav_' . $fnotext . '.wav');
        $data['filePath'] = $dir . 'wav_' . $fnotext . '.wav';
        if (!is_dir($dir)) {
            mkdir($dir, 0777, true);
        }        
        $msg = sofn_upload_handle(array('rootPath' => $dir, 'autoSub' => false, 'exts' => $allowExts, 'saveName' => 'orig_' . $fnotext), $data);
        //$msg = sofn_upload_handle($dir, array('exData' => $data, 'allowExts' => $allowExts, 'saveName' => 'orig_' . $fnotext));
        //$msg = upload_old($dir, $allowExts, 'orig_' . $fnotext, $data);
        if (!is_array($msg)) {
            $this->ajaxMsg(false, $msg);
        }
        // 转码
        $process_err = $this->process_mohfile($dir, $filename, true, $volume);
        if (isset($process_err)) {
            $this->ajaxMsg(false, $process_err);
        }
        $M = M('tgeneral_file');
        $where['dirName'] = $dirname;
        $where['exTags'] = $type;
        $n = $M->where($where)->count();
        if (!$n && $type == 'moh') {
            $data['dirname'] = $dirname;
            $data['path'] = $dir . '/';
            if (!$this->add_to_tpl($data)) {
                if ($type == 'moh') {
                    $this->force_need_reload();
                }
            }
        } else {
            if ($type == 'moh') {
                $this->force_need_reload();
            }
        }
        $this->ajaxMsg(true, '上传成功');
    }

    // /var/lib/asterisk/moh/
    // /var/lib/asterisk/moh/orig_rangmengxiangfei.mp3
    function process_mohfile($path_to_dir, $mohfile, $onlywav = false, $volume = false) {
        $amp_conf['AMPMPG123'] = 1;

        $output = 0;
        $returncode = 0;
        $mohfile = escapeshellcmd($mohfile);
        $origmohfile = $path_to_dir . "orig_" . $mohfile;
        //die($origmohfile);
        if ($amp_conf['AMPMPG123']) {
            if ($onlywav) {
                $newname = substr($mohfile, 0, strrpos($mohfile, "."));

                // If we are dealing with an MP3, we need to decode it to a wav file. mpg123 -w writes the converted output to $origmohfile.wav
                if (strtoupper(substr($origmohfile, -4)) == '.MP3') {
                    $mpg123cmd = "mpg123 -w \"" . substr($origmohfile, 0, strrpos($origmohfile, ".")) . ".wav\" \"" . $origmohfile . "\" 2>&1 ";
                    exec($mpg123cmd, $output, $returncode);
                }
                $newmohfile = $path_to_dir . "/wav_" . $newname . ".wav";
                //We need to take the output of mpg123 to use in the sox conversion. If we used $origmohfile directly then we would be bypassing mpg123. The mpg123 might not be needed on some systems if we had the sox version with mp3 compiled in. The standard rpmforge sox rpm does not have mp3 included.
                //$soxcmd = "sox \"".$origmohfile."\"";
                $source_file = substr($origmohfile, 0, strrpos($origmohfile, ".")) . ".wav";
                $soxcmd = "sox \"" . $source_file . "\"";
                $soxcmd .= " -r 8000 -c 1 \"" . $newmohfile . "\"";
                if ($volume) {
                    $soxcmd .= " vol " . $volume;
                }
                $soxresample = " rate -ql ";
                exec($soxcmd . $soxresample . "2>&1", $output, $returncode);
                if ($returncode != 0) {
                    // try it again without the resample in case the input sample rate was the same
                    //
                    $output = array();
                    $returncode = 0;
                    exec("rm -rf \"" . $newmohfile . "\"");
                    exec($soxcmd . "2>&1", $output, $returncode);
                    // if sox prints no warnings, then despite the return code we will assume it is good
                    if (empty($output)) {
                        if (copy($source_file, $newmohfile)) {
                            $returncode = 0;
                        } else {
                            $returncode = 1;
                            $output[] = _("sox failed to convert file and original could not be copied as a fall back");
                        }
                    }
                }
            }
        } else { // AMPMPG123
            $newname = strtr($mohfile, "&", "_");
            if (strstr($newname, ".mp3")) {
                $onlywav = false;
            }

            if (!$onlywav) {
                $newmohfile = $path_to_dir . "/" . ((strpos($newname, '.mp3') === false) ? $newname . ".mp3" : $newname);
                $lamecmd = "lame --cbr -m m -t -F \"" . $origmohfile . "\" \"" . $newmohfile . "\" 2>&1 ";
                if (strpos($newmohfile, '.mp3') !== false) {
                    exec($lamecmd, $output, $returncode);
                }
            } else {
                $newmohfile = $path_to_dir . "/wav_" . $newname;
                $soxcmd = "sox \"" . $origmohfile . "\" -r 8000 -c 1 \"" . $newmohfile . "\" ";
                $soxresample = "rate -ql ";
                exec($soxcmd . $soxresample . "2>&1", $output, $returncode);
                if ($returncode != 0) {
                    // try it again without the resample in case the input sample rate was the same
                    //
                    exec("rm -rf \"" . $newmohfile . "\"");
                    exec($soxcmd . "2>&1", $output, $returncode);
                }
            }
        } // AMPMPG123

        if ($returncode != 0) {
            return join("<br>\n", $output);
        }
        $rmcmd = "rm -f \"" . $origmohfile . "\"";
        exec($rmcmd);
        if ($amp_conf['AMPMPG123']) {
            // If this started as an mp3, we converted it to a wav and then transcoded it from there,
            // so we have two "original" files to delete
            //
            if (strpos($origmohfile, '.mp3') | strpos($origmohfile, '.MP3') !== false) {
                $rmcmd = "rm -f \"" . substr($origmohfile, 0, strrpos($origmohfile, ".")) . ".wav\"";
                exec($rmcmd);
            }
        } // AMPMPG123
        return null;
    }

    // 如果是等待音则需要加入配置表
    function add_to_tpl($data, $activated = true) {
        if ($data) {
            if (!file_exists(musiconhold_additional_path)) {
                //$this->ajaxMsg(false,'配置文件不存在', '?s=VocFile/');
                return false;
            }
            if (!is_writable(musiconhold_additional_path)) {
                //$this->ajaxMsg(false,'配置文件不允许读写', '?s=VocFile/');
                return false;
            }

            $file_content = file_get_contents(musiconhold_additional_path);
            if ($activated) {
                if (strstr($file_content, '[' . $data['dirname'] . ']')) {
                    //$this->ajaxMsg(false,'配置文件中已包含此分机', '?s=VocFile/');
                    return false;
                }
                $content = musiconhold_additional_tpl;
                $content = str_replace("{dirname}", $data["dirname"], $content);
                $content = str_replace("{path}", $data["path"], $content);
                $fp = fopen(musiconhold_additional_path, 'a+');
                fwrite($fp, $content);
                fclose($fp);
                $this->ajax_cti_reload('?s=VocFile/');
                return true;
            } else {
                if (strstr($file_content, '[' . $data['dirname'] . ']')) {
                    $file_content = ereg_replace('\[' . $data['dirname'] . '[^\[]*[^\[]?', "", $file_content);
                    file_put_contents(musiconhold_additional_path, $file_content);
                }
                $this->ajax_cti_reload('?s=VocFile/');
                return true;
            }
        }
    }

    public function item_delete($id = '') {
        if (!$id) {
            $this->ajaxMsg(false, '编号无效!');
        }
        $where['id'] = array('in', $id);
        $M = M('tgeneral_file');
        $paths = $M->where($where)->getField('filePath', true);
        $result = $M->where($where)->delete();
        if (FALSE !== $result) {
            foreach ($paths as $path) {
                unlink($path);
            }
            $this->force_need_reload();
        }
        $this->ajaxMsg($result, '删除{%}');
    }

    function get_insert_sqls($dir_path, $tag = '', $deep = 0) {
        $arr = array();
        if ($handle = opendir($dir_path)) {
            while (false !== ($file = readdir($handle))) {
                if ($file == "." || $file == "..")
                    continue;
                $path = $dir_path . "/" . $file;
                if ((is_dir($path))) {
                    //$arr[] = sprintf("insert into tgeneral_file (fileName,filePath,fileType,fileSize,createdTime,dirName,exTags) values ('%s','%s','%s','%s','%s','%s','%s');", $file, $path, filetype($path), filesize($path), date('Y-m-d H:m:s', filemtime($path)), dirname($path), $tag);
                    $arr = array_merge($arr, $this->get_insert_sqls($path, $tag, $deep + 1));
                    continue;
                }
                $ext = sofunc_get_file_ext($path);
                if (strpos(',mp3,wav,g729,', $ext)) {
                    $lastdir = sofunc_get_last_dir_name(dirname($path));
                    if (strpos($lastdir, 'xcall_') > -1) {
                        $arr[] = sprintf("insert into tgeneral_file (fileName,filePath,fileType,fileExt,fileSize,createdTime,dirName,exTags) values ('%s','%s','%s','%s','%s','%s','%s','%s');", $file, $path, filetype($path), $ext, filesize($path), date('Y-m-d H:m:s', filemtime($path)), $lastdir, $tag);
                    }
                }
            }
            closedir($handle);
        }
        return $arr;
    }

}
